package rest

import (
	"errors"
	"github.com/gin-gonic/gin"
	"github.com/go-playground/validator/v10"
	"github.com/sirupsen/logrus"
	"monoblog/common"
	"monoblog/domain/auth"
	"monoblog/domain/dto"
	"monoblog/domain/service"
)

/*
用户&账号接口
*/

// 根据UserId获取用户数据
func FindUserByUserID(ctx *gin.Context) {
	id := ctx.Param("id")
	user, err := service.GetUserService().FindByUserId(ctx, id)
	if err != nil {
		common.Fail(ctx, "查询用户失败", err)
		return
	}
	common.Success(ctx, user)
}

// 根据UserId获取用户详情数据
func FindUserDetail(ctx *gin.Context) {
	userId := ctx.Param("userId")
	user, err := service.GetUserService().FindFullByUserId(ctx, userId)
	if err != nil {
		common.Fail(ctx, "查询用户失败", err)
		return
	}
	common.Success(ctx, user)
}

func FindUserPage(ctx *gin.Context) {
	var query dto.UserQuery

	if err := ctx.ShouldBind(&query); err != nil {
		common.Fail(ctx, "Query数据绑定失败", err)
		return
	}

	users, err := service.GetUserService().FindPage(ctx, query)
	if err != nil {
		common.Fail(ctx, "查询用户列表失败", err)
		return
	}
	common.Success(ctx, users)
}

// RegisterUser 注册用户
func RegisterUser(ctx *gin.Context) {
	var form dto.UserRegisterReqForm
	if err := ctx.ShouldBind(&form); err != nil {
		common.Fail(ctx, "Body数据绑定失败", err)
		return
	}
	//初始化校验器并执行字段校验
	validate := validator.New()
	if err := validate.Struct(form); err != nil {
		common.Fail(ctx, "参数校验失败", err)
		return
	}
	// 校验验证码 phone
	if !auth.SmsCodeVerify(ctx, form.VerifyCode, form.Phone) {
		common.Fail(ctx, "验证码错误", errors.New("verify code invalid. :"+form.VerifyCode))
		return
	}

	exists, err := service.GetUserService().ExistsByUserId(ctx, form.Username)
	if exists {
		common.Fail(ctx, "username已被注册", err)
		return
	}
	//创建用户账号
	err = service.GetUserService().AddUser(ctx, form)
	if err != nil {
		common.Fail(ctx, "注册用户失败", err)
		return
	}
	logrus.Infof("[aid: %s] 注册用户成功: %v", ctx.Value("aid"), form.Username)
	common.Success(ctx, nil)
}

// UserToFollow 当前用户去关注id用户
func UserToFollow(ctx *gin.Context) {
	followId := ctx.Param("id") // 被关注人的ID
	var userId string           // 用户ID

	if user, ok := ctx.Get("user"); ok {
		userId = user.(*auth.LoginUser).UID
	}
	if userId == "" {
		common.Fail(ctx, "用户未登录", errors.New("user not login"))
		return
	}

	service := service.GetInterestService()

	service.UserToFollow(ctx, followId, userId)

	common.Success(ctx, nil)
}

// CancelFollow 当前用户去关注id用户
func CancelFollow(ctx *gin.Context) {
	followId := ctx.Param("id") // 被关注人的ID
	var userId string           // 用户ID

	if user, ok := ctx.Get("user"); ok {
		userId = user.(*auth.LoginUser).UID
	}
	if userId == "" {
		common.Fail(ctx, "用户未登录", errors.New("user not login"))
		return
	}

	service := service.GetInterestService()

	service.UserCancelFollow(ctx, followId, userId)

	common.Success(ctx, nil)
}

// UserToBlack 当前用户去拉黑id用户
func UserToBlack(ctx *gin.Context) {
	blackId := ctx.Param("id") // 被关注人的ID
	var userId string          // 用户ID

	if user, ok := ctx.Get("user"); ok {
		userId = user.(*auth.LoginUser).UID
	}
	if userId == "" {
		common.Fail(ctx, "用户未登录", errors.New("user not login"))
		return
	}

	err := service.GetInterestService().UserToFollow(ctx, blackId, userId)
	if err != nil {
		common.Fail(ctx, "拉黑失败", err)
		return
	}

	common.Success(ctx, nil)
}

// UserCancelBlack 当前用户去取消拉黑id用户
func UserCancelBlack(ctx *gin.Context) {
	blackId := ctx.Param("id") // 被关注人的ID
	var userId string          // 用户ID

	if user, ok := ctx.Get("user"); ok {
		userId = user.(*auth.LoginUser).UID
	}
	if userId == "" {
		common.Fail(ctx, "用户未登录", errors.New("user not login"))
		return
	}

	err := service.GetInterestService().UserCancelFollow(ctx, blackId, userId)
	if err != nil {
		common.Fail(ctx, "取消拉黑失败", err)
		return
	}

	common.Success(ctx, nil)
}
